package net.brucecooper.mindmap.client;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import com.google.gwt.xml.client.Document;
import com.google.gwt.xml.client.Element;
import com.google.gwt.xml.client.NodeList;

public class DummyNodeStore extends AbstractNodeDataStore {

    int nodeCounter = 0;

    Map<Integer, Node> nodes = new HashMap<Integer, Node>();

    private NodeOrientation rootNodeOrientation = NodeOrientation.RIGHT;

    
    private int getNumChildren(int node) {
        switch (node) {
        case 0:
            return 5;
        case 1:
            return 2;
        case 4:
            return 4;
        case 5:
            return 30;
        case 6:
            return 3;
        case 12:
            return 2;

        default:
            return 0;
        }
    }

    
    @Override
    protected Node getNode(int id) {

        Node n = nodes.get(id);

        if (n == null) {
            ArrayList<Integer> kids = new ArrayList<Integer>();
            int num = getNumChildren(id);
            for (int i = 0; i < num; i++) {
                kids.add(++nodeCounter);
            }
            n = new Node(id, "Node " + id, kids);
            nodes.put(id, n);
            
            if (id == 3) {
                ArrayList<String> up = new ArrayList<String>();
                ArrayList<String> down = new ArrayList<String>();
                
                up.add("one@somewhere.com");
                up.add("two@somewhere.com");
                up.add("three@somewhere.com");
                up.add("four@somewhere.com");
                
                down.add("five@somewhere.com");
                
                n.votesDown = down;
                n.votesUp = up;
            }
            
            if (id == 4) {
                n.collapsedInitially = true;
            }
            
            if (id == 0) {
                n.outline = NodeOutlineStyle.CIRCLE;
            }
            if (id == 1) {
                n.outline = NodeOutlineStyle.CLOUD;
            }
                
        }
        return n;
    }
    
    public int addChildTo(int node) {
        Node newChild = new Node(++nodeCounter, "", new ArrayList<Integer>());
        Node pn = getNode(node);
        pn.children.add(newChild.id);
        fireNodeAdded(node, newChild.id);
        return newChild.id;
    }
    
    public void removeNodeFrom(int parentNode, int id) {
        // we explicitly cast to an integer here so that it removes the value, not the index.
        getNode(parentNode).children.remove( new Integer(id));
        fireNodeDeleted(parentNode, id);
    }

	public void setNodeName(int node, String newName) {
		getNode(node).name = newName;
		fireNodeChanged(node);
	}

    public void replaceModel(Document newModel) {

        nodeCounter = populateModel((Element)newModel.getElementsByTagName("node").item(0), ROOT_NODE);
        fireModelChanged();
    }

    private int populateModel(Element e, int id) {
        int myID = id;
        NodeList children = e.getElementsByTagName("node");
        ArrayList<Integer> childIDs = new ArrayList<Integer>();

        if (children != null) {
            for (int i = 0; i < children.getLength(); i++) {
                Element childObj = (Element) children.item(i);
                int newID = ++id;
                id = populateModel(childObj, id);
                childIDs.add(newID);
            }
        }
        String name = e.getAttribute("TEXT");
        Node n = new Node(id, name, childIDs);
        
        
        NodeList iconElem = e.getElementsByTagName("icon");
        if (iconElem != null && iconElem.getLength() > 0) {
            String builtin = ((Element)iconElem.item(0)).getAttribute("BUILTIN");
            n.icon = builtin;
        }
        
        nodes.put(myID, n);
        return id;
    }
	
	public void setIcon(int node, String newIcon) {
		getNode(node).icon = newIcon;
		fireNodeChanged(node);
	}
    public void changeNodeParent(int nodeID, int oldParent, int newParent) {
        Node oldParentNode = getNode(oldParent);
        Node newParentNode = getNode(newParent);
        
        oldParentNode.children.remove(new Integer(nodeID));
        newParentNode.children.add(new Integer(nodeID));
        
        fireNodeDeleted(oldParent, nodeID);
        fireNodeAdded(newParent, nodeID);
    }

    public void voteForNode(int nodeID, String username, boolean voteUp) {
        Node node = getNode(nodeID);
        
        if (voteUp) {
            if (node.votesDown != null) {
                node.votesDown.remove(username);
            }
            if (node.votesUp == null) {
                node.votesUp = new ArrayList<String>();
            }
            if (!node.votesUp.contains(username)) {
                node.votesUp.add(username);
            }
        } else {
            if (node.votesUp != null) {
                node.votesUp.remove(username);
            }
            if (node.votesDown == null) {
                node.votesDown = new ArrayList<String>();
            }
            if (!node.votesDown.contains(username)) {
                node.votesDown.add(username);
            }
        }
        fireNodeChanged(nodeID);
        
    }

    public boolean isReady() {
        return true;
    }

    public void setNodeOutline(int nodeID, NodeOutlineStyle style) {
        getNode(nodeID).outline = style;
        
    }

    

    public void setNodeCollapsedInitially(int nodeID, boolean collapsed) {
        getNode(nodeID).collapsedInitially = collapsed;
    }

    public NodeOrientation getRootNodeOrientation() {
        return rootNodeOrientation;
    }
    public void setRootNodeOrientation(NodeOrientation orientation) {
        this.rootNodeOrientation = orientation;
    }
    
    public void setNodeForeground(int id, String rgb) {
        getNode(id).foreground = rgb;
        
    }
    public void setNodeBackground(int id, String rgb) {
        getNode(id).background = rgb;
        
    }

    
    
    
    
}
